/* types */
import { BaseSelectUserSelectedItemType } from '@src/component/common/BaseSelectUser/types'
/* hooks */
import { useBaseSelectUserOptions } from '@src/component/common/BaseSelectUser/hooks/options'
/* model */
import { BaseSelectUserSelectedItem, BaseSelectUserTree, SelectUserComponentDepartment } from '@src/component/common/BaseSelectUser/model'
/* vue */
import { computed, ComputedRef } from 'vue'
/* store */
import { useBaseSelectUserStoreCheckedItemList } from '@src/component/common/BaseSelectUser/store'
/* util */
import { 
  getCheckedItemId, 
  getCheckedItemImage, 
  getCheckedItemName, 
  getCheckedItemStaffId, 
  getCheckedItemUserTypeList,
  getCheckedItemTypeId, 
  getCheckedItemDisabled,
  isDepartmentSelectType, 
  isDisabledSelectItem, 
  isRoleSelectType, 
  isServiceProviderSelectType, 
  isTagSelectType
} from '@src/component/common/BaseSelectUser/util'
import { message } from '@src/util/message'
import { isFalsy } from '@src/util/type'

function useSelectUserCheckedItemList() {
  
  const { checkedItemList, checkedItemListIdMap, setCheckedItemList } = useBaseSelectUserStoreCheckedItemList()
  
  // 已选中部门列表
  const checkedDepartmentItemList = computed(() => {
    return checkedItemList.value.filter(item => isTagSelectType(item) || isDepartmentSelectType(item))
  })
  
  // 已选中角色列表
  const checkedRoleItemList = computed(() => {
    return checkedItemList.value.filter(item => isRoleSelectType(item))
  })
  
  // 已选中服务商列表
  const checkedServiceProviderItemList = computed(() => {
    return checkedItemList.value.filter(item => isServiceProviderSelectType(item))
  })
  
  // 已选中列表给组件使用的
  const checkedItemListForComponent: ComputedRef<BaseSelectUserSelectedItem[]> = computed(() => {
    return checkedItemList.value.map(item => {
      return {
        img: getCheckedItemImage(item),
        name: getCheckedItemName(item),
        id: getCheckedItemId(item),
        typeId: getCheckedItemTypeId(item),
        staffId: getCheckedItemStaffId(item),
        userTypeList: getCheckedItemUserTypeList(item),
        disabled: getCheckedItemDisabled(item)
      }
    })
  })
  
  // 添加已选择项
  const addCheckedItem = (item: BaseSelectUserSelectedItemType) => {
    
    let newItem = {
      ...item
    }
    
    // 兼容处理，添加部门时，如果没有 dingId，则使用 name 作为dingId
    if (isDepartmentSelectType(item) && isFalsy((item as SelectUserComponentDepartment)?.dingId)) {
      (newItem as SelectUserComponentDepartment).dingId = (item as SelectUserComponentDepartment).name
    }
    
    const newCheckedItemList = [...checkedItemList.value, newItem]
    
    setCheckedItemList(newCheckedItemList)
  }
  
  // 删除已选择项
  const removeCheckedItem = (item: BaseSelectUserSelectedItemType) => {
    
    const index = checkedItemList.value.findIndex(checkedItem => {
      return getCheckedItemId(checkedItem) === getCheckedItemId(item)
    })
    
    removeCheckedItemByIndex(index)
    
  }
  
  const updateCheckedItem = (newItem: BaseSelectUserSelectedItemType) => {

    const index = checkedItemList.value.findIndex(checkedItem => {
      return getCheckedItemId(checkedItem) === getCheckedItemId(newItem)
    })
    
    let newCheckedItemList: BaseSelectUserSelectedItemType[] = checkedItemList.value.slice()
    
    if (index > -1) {
      newCheckedItemList[index] = newItem
      setCheckedItemList(newCheckedItemList)
    }
    
  }
  
  // 删除已选择项从索引
  const removeCheckedItemByIndex = (index: number) => {
    
    if (index >= 0) {
      
      const newCheckedItemList = [
        ...checkedItemList.value.slice(0, index), 
        ...checkedItemList.value.slice(index + 1)
      ]
      
      setCheckedItemList(newCheckedItemList)
      
    }
    
  }
  
  // 清空所有已选择项
  const removeAllCheckedItem = () => {
    const disableItemList = checkedItemList.value.filter(item => {
      return getCheckedItemDisabled(item)
    })
    
    setCheckedItemList(disableItemList)
  }


  
  const isSelectedByUserId = (userId: string) => {
    return Boolean(checkedItemListIdMap.value[userId]) 
  }
  
  return {
    checkedItemList,
    checkedDepartmentItemList,
    checkedRoleItemList,
    checkedServiceProviderItemList,
    checkedItemListIdMap,
    checkedItemListForComponent,
    
    setCheckedItemList,
    addCheckedItem,
    removeCheckedItem,
    updateCheckedItem,
    removeCheckedItemByIndex,
    removeAllCheckedItem,
    isSelectedByUserId
  }
  
}

function useSelectUserChecked(props?: { value: BaseSelectUserSelectedItemType }) {
  
  const { checkedItemList, checkedItemListIdMap } = useBaseSelectUserStoreCheckedItemList()
  const { getOptionsMax, isInfiniteOptionsMax } = useBaseSelectUserOptions()
  
  const item: ComputedRef<BaseSelectUserSelectedItemType | undefined> = computed(() => {
    return props?.value
  })
  
  const checkIsChecked = (item: BaseSelectUserSelectedItemType | BaseSelectUserTree) => {
    return Boolean(checkedItemListIdMap.value[getCheckedItemId(item)])
  }
  
  const checkIsDisabled = (item: BaseSelectUserSelectedItemType | BaseSelectUserTree) => {
    
    const isDisabledSelect = isDisabledSelectItem(item as BaseSelectUserSelectedItemType)
    
    if (isInfiniteOptionsMax.value) {
      return isDisabledSelect
    }
    
    if (isChecked.value) {
      return isDisabledSelect
    }
    
    if (checkedItemList.value.length >= getOptionsMax.value) {
      return true
    }
    
    return isDisabledSelect
    
  }
  
  const isChecked: ComputedRef<boolean> = computed(() => {
    
    if (item.value) {
      return checkIsChecked(item.value)
    }
    
    return false
  })
  
  const isDisabled: ComputedRef<boolean> = computed(() => {
    return Boolean(item.value && checkIsDisabled(item.value))
  })
  
  const selectLimitMessage = () => {
    message.warning(`超过上限${getOptionsMax.value}个`)
  }
  
  return {
    isChecked,
    isDisabled,
    checkIsChecked,
    checkIsDisabled,
    selectLimitMessage
  }
}

function useSelectUserIsShowCheckbox() {
  
  const { isCanChooseDepartment, isCanChooseRole, isCanChooseServiceProvider, isCanChooseUser, isMulti } = useBaseSelectUserOptions()
  
  const isShowDepartmentCheckbox = computed(() => {
    return isCanChooseDepartment.value && isMulti.value
  })
  
  const isShowRoleCheckbox = computed(() => {
    return isCanChooseRole.value && isMulti.value
  })
  
  const isShowUserCheckbox = computed(() => {
    return isCanChooseUser.value && isMulti.value
  })
  
  const isShowServiceProviderCheckbox = computed(() => {
    return isCanChooseServiceProvider.value && isMulti.value
  })
  
  return {
    isShowDepartmentCheckbox,
    isShowRoleCheckbox,
    isShowUserCheckbox,
    isShowServiceProviderCheckbox,
  }
}

export {
  useSelectUserCheckedItemList,
  useSelectUserChecked,
  useSelectUserIsShowCheckbox
}
